package com.atguigu.spring6.aop.annoaop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {

    // 设置切入点和通知类型
    // 通知类型： 前置通知（@Before）、返回通知(@AfterReturning)、异常通知(@AfterThrowing)、最终通知(@After)、环绕通知(@Around)

//    @Before("execution(* com.atguigu.spring6.aop.annoaop.Calulator.*(..))")
    @Before("pointCut()") // 重用切入点表达式
    public void beforeMethod(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        System.out.println("Logger-->前置通知，方法是：" + name);
    }

    @After("execution(* com.atguigu.spring6.aop.annoaop.Calulator.*(..))")
    public void afterMethod(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("Logger-->后置通知，方法是：" + name + "方法执行参数是：" + args.toString());
    }

    @AfterReturning(value = "execution(* com.atguigu.spring6.aop.annoaop.Calulator.*(..))", returning = "result")
    public void afterReturningMethod(JoinPoint joinPoint, Object result) {
        String name = joinPoint.getSignature().getName();
        System.out.println("Logger-->返回通知，结果是：" + name + "方法执行结果是：" + result);
    }

    @AfterThrowing(value = "execution(* com.atguigu.spring6.aop.annoaop.Calulator.*(..))", throwing = "e")
    public void afterThrowingMethod(JoinPoint joinPoint, Throwable e) {
        String name = joinPoint.getSignature().getName();
        System.out.println("Logger-->异常通知，方法是：" + name + "异常信息：" + e.getMessage());
    }

    @Around("execution(* com.atguigu.spring6.aop.annoaop.Calulator.*(..))")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) {
        Object result = null;
        try {
            System.out.println("环绕通知-->前置");
            // 被增强的方法执行
            result = joinPoint.proceed();
            System.out.println("环绕通知-->后置");
        } catch (Throwable e) {
            System.out.println("环绕通知-->异常信息" + e.getMessage());
        } finally {
            System.out.println("环绕通知-->最终");
        }

        return result;
    }

    // 重用切入点表达式
    @Pointcut("execution(* com.atguigu.spring6.aop.annoaop.Calulator.*(..))")
    public void pointCut() {

    }
}
